package com.mycompany.project.client;

import com.smartgwt.client.types.DragAppearance;
import com.smartgwt.client.widgets.WidgetCanvas;
import com.google.gwt.user.client.ui.TextArea;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.AnimationEffect;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.widgets.events.ResizedHandler;
import com.smartgwt.client.widgets.events.ResizedEvent;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.MouseOverHandler;
import com.smartgwt.client.widgets.events.MouseOverEvent;
import com.smartgwt.client.widgets.events.MouseOutHandler;
import com.smartgwt.client.widgets.events.MouseOutEvent;
import com.google.gwt.event.dom.client.DoubleClickHandler;
import com.google.gwt.event.dom.client.DoubleClickEvent;
import com.google.gwt.event.shared.HandlerManager;

/**
 * @author Laboratorio Tv Collaborativa/Contenuti Digitali --> Sardegna District --> Crs4 --> Sardegna Ricerche
 * 
 * This Class Implements a Text Box container like a post-it object. This text box
 * is graphically similar at Post-It where you can enter notes. As in the Post-It
 * in this box container you can insert the electronics notes. In @SaStria project
 * this object is used to write and insert the note about the video Annotation, so
 * it is the visible annotation Tag showed on player of @SaStria annotations tool. 
 * This Text box can be moved, dragged, resized, for cover all' interesting Video Area.
 */
public class AnnotationTag extends VLayout{
	private static final int borderSize=15;    //Size in pixel of annotation box container. 10px for text area container + "5px" for text area
	private TextArea annotationArea;   // Text Area where the user write and read the note of annotation tag
	private WidgetCanvas annotationTextContainer; // Container of text box area
	private Label labelSaStria;  // label where to show the word "@SaStria". It has no function but is showed only for good looking
	private static final int animateDuration=700;   // Length in milliseconds for the opening and closing animation of annotation Tag  
	private boolean isOpened;   // if true the Annotation tag is visible on video player. false otherwise.
	private HandlerManager handleManagerSaved;  // handle manager for fire the AnnotationSaveEvent and consequently the onAnnotationSaved event 
												// used for save the status of annotations.
	
	
	
	/**
	 * This methods set the dimension of the Annotation Text Area according with the AnnotationTextContainer size.
	 * The AnnotationTextContainer is the container box of TextArea component 
	 */
	private void setDimmension(){			
		int width=annotationTextContainer.getOffsetWidth()-2*borderSize; //get the width as annotationTextContainer width minus "border size *2(right+left)"  
		int height=annotationTextContainer.getOffsetHeight()-2*borderSize; //get the height as annotationTextContainer height minus "border size *2(top+bottom)"		
		annotationArea.setSize(width+"px", height+"px"); // set the new size.	
	}
	
	
	/**
	 * This is the constructor of this class that create the AnnotationTag object.
	 * The annotationTag object is visually divided in two layer, Top and bottom layer.
	 * Top Layer deals the 100% available space in Horizontally and the (100% - 20px) in
	 * vertically. It show the annotationTextContainer container and the annotationArea text Box.
	 * Bottom layer deals the 100% available space in Horizontally and 20px in vertically. 
	 * It show the label without no function(only for good looking) that contain the 
	 * word @SaStria. 
	 * This constructor also sets the coordinate position X and Y within the media player area.   
	 * @param xPos: integer value indicating the X position coordinate within the media player area
	 * used for set the x position of annotationTag
	 * @param yPos: : integer value indicating the Y position coordinate within the media player area
	 * used for set the Y position of annotationTag 
	 */
	public AnnotationTag(int xPos,int yPos) {
		
		handleManagerSaved=new HandlerManager(null);  // create the handle manager for dispatch the onAnnotationMoved event when the user move the AnnotationTag
		isOpened=true;    // set the annotation as visible and open
		addResizedHandler(new ResizedHandler() {
			public void onResized(ResizedEvent event) { // on resize the AnnotationTag the Text Area box must be resized 
			setDimmension();   // resize the annotation Text Area according to the new size of AnnotationTag
			}
		});
		annotationArea = new TextArea();   // create the Annotation Text area box
		annotationArea.addDoubleClickHandler(new DoubleClickHandler() {
			public void onDoubleClick(DoubleClickEvent event) {  // on double click on Annotation Text area box, AnnotationTag must be closed
				isOpened=false;    // set the AnnotationTag as closed and invisible
				animateHide(AnimationEffect.FADE, null, animateDuration);	// run the AnnotationTag closing animation. 	
				handleManagerSaved.fireEvent(new AnnotationSaveEvent());  // fires the AnnotationSaveEvent event to inform event handler listeners.
			}
		});
				
		annotationTextContainer = new WidgetCanvas(annotationArea);	// create the annotationText container that contain the annotationArea text area box			
		
		this.setCanDragReposition(true);  // The AnnotationTag can be dragged and repositioned   
		this.setCanDragResize(true);  // The AnnotationTag can be resized
		/*
		 * There are different types of effects for showing dragging behavior 
		 * OUTLINE : An outline the size of the target object is moved, resized, etc.
		 * TARGET :  The target object is actually moved, resized, etc.
		 * */
		this.setDragAppearance(DragAppearance.TARGET); 		
		this.setChildrenSnapResizeToGrid(true); //If true, causes this canvas's children to snap to its grid when resizing.
		this.setOverflow(Overflow.HIDDEN);  // Content that extends beyond the widget's width or height is clipped (hidden).
		this.setMinHeight(70);  // set min height size
		this.setMinWidth(70);   // set min width size
		setSize("100px", "100px"); // set size as 100X100 px
		addMouseOutHandler(new MouseOutHandler() {
			public void onMouseOut(MouseOutEvent event) {  //when the mouse leaves the AnnotationTag area change the style that hide the drag border
				setStyleName("AnnotationBox");	 // set the style that hide the drag border
				
			}
		});
		addMouseOverHandler(new MouseOverHandler() {
			public void onMouseOver(MouseOverEvent event) {  //when the mouse enter on the AnnotationTag area change the style that show the drag border
				setStyleName("AnnotationBoxSelected"); // set the style that show the drag border
			}
		});
		setLeft(xPos); // set the X position of AnnotationTag 
		setTop(yPos);  // set the Y position of AnnotationTag
		setStyleName("AnnotationBox");	// set the default style that hide the drag border(not selected style) 		
		annotationTextContainer.setStyleName("TextAreaContainer"); //set the style name of annotationTextContainer
		annotationArea.setStyleName("TextArea");  //set the style name of annotationArea
		labelSaStria = new Label();  // create a new label for display the word "@SaStria.crs4.it".
	    labelSaStria.setContents("@SaStria.crs4.it");  // display the word "@SaStria.crs4.it".
	    setAlign(Alignment.CENTER);   // sets the CENTER Alignment of AnnotationTag 
	    annotationTextContainer.setAlign(Alignment.CENTER); // sets the CENTER Alignment of annotationTextContainer
	    labelSaStria.setAlign(Alignment.CENTER); // sets the CENTER Alignment of labelSaStria
		addMember(annotationTextContainer);  // add annotationTextContainer container to AnnotationTag. 
		addMember(labelSaStria); // add labelSaStria to AnnotationTag.		
		annotationTextContainer.setSize("100%", "*"); // sets width 100% size and (100%-20px) height size. the "*" is used for (100%-20px).
		labelSaStria.setSize("100%", "20px"); // sets labelSaStria as 100% width and 20px height
		this.animateShow(AnimationEffect.FADE, null, animateDuration); // start the animation that show the AnnotationTag on @SaStria video Player
					
	}
	
	
	/**
	 * This method sets the Annotation style name. AnnotationBoxSelected show a resize and drag and drop border.
	 *  AnnotationBoxSelected hide a resize and drag and drop border. 
	 * @param value : boolean value. If true set the AnnotationBoxSelected that display borders, false otherwise  
	 */
	public void setSelected(boolean value){
		if(value)
			this.setStyleName("AnnotationBoxSelected");
		else
			this.setStyleName("AnnotationBox");
	}
	
	
	/**
	 * This method get AnnotationTag selected status according to stylename value.  
	 * @return boolean value. If true AnnotationTag has focus and "AnnotationBoxSelected"
	 * is the current style. false otherwise.
	 */
	public boolean getSelected(){
		boolean returnValue;
		if(this.getStyleName().compareTo("AnnotationBoxSelected")==0) // if stylename is AnnotationBoxSelected then Annotation tag has focus
			returnValue=true;
		else
			returnValue=false;
		return(returnValue);
	}
	
	
	/**
	 * This method force the AnnotaionTag draw and open. The opening/drawing process is realized as
	 * an animation that draw the AnnotationTag slowly.   
	 */
	public void forceDraw(){
		isOpened=true;
		this.animateShow(AnimationEffect.FADE, null, animateDuration);
	}
	
	
	/**
	 * This method force the AnnotaionTag close and hide. The hiding/closing process is realized as
	 * an animation that hide the AnnotationTag slowly.
	 */
	public void forceHide(){
		isOpened=false;
		this.animateHide(AnimationEffect.FADE, null, animateDuration);		
	}
	
	
	/**
	 * This method gets the visible status of AnnotaionTag 
	 * @return boolean value: if true the AnnotationTag is visible, false otherwise
	 */
	public boolean getIsVisible(){
		return(isOpened);
	}
	
	
	/**
	 * This method add a AnnotationSaveEventHandler handler. This is executed when a double
	 * click of mouse occurs on AnnotationTag
	 * @param handler: the AnnotationSaveEventHandler handler
	 */
	public void addAnnotationSaveHandler(AnnotationSaveEventHandler handler){
		handleManagerSaved.addHandler(AnnotationSaveEvent.TYPE, handler);
	}
	
	/**
	 * This method add a string to the current word showed on labelSaStria.
	 * @param value: String to add at the current word showed on labelSaStria.
	 */
	@Deprecated 
	public void addContentToLabelSaStria(String value){
		labelSaStria.setContents(labelSaStria.getContents() + "-" + value);
	}
	
	
	/**
	 * This method set the content value of AnnotationTag and in particular mode
	 * sets the text to display on Annotation Text Box Area. 
	 * @param value
	 */
	public void setContentValue(String value){
		annotationArea.setText(value);
	}
}
